//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_exported import SotoCore

/// Service object for interacting with AWS Invoicing service.
///
///  Amazon Web Services Invoice Configuration  You can use Amazon Web Services Invoice Configuration APIs to programmatically create, update, delete, get, and list invoice units. You can also programmatically fetch the information of the invoice receiver. For example, business legal name, address, and invoicing contacts.  You can use Amazon Web Services Invoice Configuration to receive separate Amazon Web Services invoices based your organizational needs. By using Amazon Web Services Invoice Configuration, you can configure invoice units that are groups of Amazon Web Services accounts that represent your business entities, and receive separate invoices for each business entity. You can also assign a unique member or payer account as the invoice receiver for each invoice unit. As you create new accounts within your Organizations using Amazon Web Services Invoice Configuration APIs, you can automate the creation of new invoice units and subsequently automate the addition of new accounts to your invoice units. Service endpoint You can use the following endpoints for Amazon Web Services Invoice Configuration:    https://invoicing.us-east-1.api.aws
public struct Invoicing: AWSService {
    // MARK: Member variables

    /// Client used for communication with AWS
    public let client: AWSClient
    /// Service configuration
    public let config: AWSServiceConfig

    // MARK: Initialization

    /// Initialize the Invoicing client
    /// - parameters:
    ///     - client: AWSClient used to process requests
    ///     - region: Region of server you want to communicate with. This will override the partition parameter.
    ///     - partition: AWS partition where service resides, standard (.aws), china (.awscn), government (.awsusgov).
    ///     - endpoint: Custom endpoint URL to use instead of standard AWS servers
    ///     - middleware: Middleware chain used to edit requests before they are sent and responses before they are decoded 
    ///     - timeout: Timeout value for HTTP requests
    ///     - byteBufferAllocator: Allocator for ByteBuffers
    ///     - options: Service options
    public init(
        client: AWSClient,
        region: SotoCore.Region? = nil,
        partition: AWSPartition = .aws,
        endpoint: String? = nil,
        middleware: AWSMiddlewareProtocol? = nil,
        timeout: TimeAmount? = nil,
        byteBufferAllocator: ByteBufferAllocator = ByteBufferAllocator(),
        options: AWSServiceConfig.Options = []
    ) {
        self.client = client
        self.config = AWSServiceConfig(
            region: region,
            partition: region?.partition ?? partition,
            amzTarget: "Invoicing",
            serviceName: "Invoicing",
            serviceIdentifier: "invoicing",
            serviceProtocol: .json(version: "1.0"),
            apiVersion: "2024-12-01",
            endpoint: endpoint,
            errorType: InvoicingErrorType.self,
            middleware: middleware,
            timeout: timeout,
            byteBufferAllocator: byteBufferAllocator,
            options: options
        )
    }





    // MARK: API Calls

    /// This gets the invoice profile associated with a set of accounts. The accounts must be linked accounts under the requester management account organization.
    @Sendable
    @inlinable
    public func batchGetInvoiceProfile(_ input: BatchGetInvoiceProfileRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> BatchGetInvoiceProfileResponse {
        try await self.client.execute(
            operation: "BatchGetInvoiceProfile", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// This gets the invoice profile associated with a set of accounts. The accounts must be linked accounts under the requester management account organization.
    ///
    /// Parameters:
    ///   - accountIds: Retrieves the corresponding invoice profile data for these account IDs.
    ///   - logger: Logger use during operation
    @inlinable
    public func batchGetInvoiceProfile(
        accountIds: [String],
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> BatchGetInvoiceProfileResponse {
        let input = BatchGetInvoiceProfileRequest(
            accountIds: accountIds
        )
        return try await self.batchGetInvoiceProfile(input, logger: logger)
    }

    /// This creates a new invoice unit with the provided definition.
    @Sendable
    @inlinable
    public func createInvoiceUnit(_ input: CreateInvoiceUnitRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> CreateInvoiceUnitResponse {
        try await self.client.execute(
            operation: "CreateInvoiceUnit", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// This creates a new invoice unit with the provided definition.
    ///
    /// Parameters:
    ///   - description:  The invoice unit's description. This can be changed at a later time.
    ///   - invoiceReceiver:  The Amazon Web Services account ID chosen to be the receiver of an invoice unit. All invoices generated for that invoice unit will be sent to this account ID.
    ///   - name:  The unique name of the invoice unit that is shown on the generated invoice. This can't be changed once it is set. To change this name, you must delete the invoice unit recreate.
    ///   - resourceTags:  The tag structure that contains a tag key and value.
    ///   - rule: The InvoiceUnitRule object used to create invoice units.
    ///   - taxInheritanceDisabled: Whether the invoice unit based tax inheritance is/ should be enabled or disabled.
    ///   - logger: Logger use during operation
    @inlinable
    public func createInvoiceUnit(
        description: String? = nil,
        invoiceReceiver: String,
        name: String,
        resourceTags: [ResourceTag]? = nil,
        rule: InvoiceUnitRule,
        taxInheritanceDisabled: Bool? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> CreateInvoiceUnitResponse {
        let input = CreateInvoiceUnitRequest(
            description: description, 
            invoiceReceiver: invoiceReceiver, 
            name: name, 
            resourceTags: resourceTags, 
            rule: rule, 
            taxInheritanceDisabled: taxInheritanceDisabled
        )
        return try await self.createInvoiceUnit(input, logger: logger)
    }

    /// This deletes an invoice unit with the provided invoice unit ARN.
    @Sendable
    @inlinable
    public func deleteInvoiceUnit(_ input: DeleteInvoiceUnitRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> DeleteInvoiceUnitResponse {
        try await self.client.execute(
            operation: "DeleteInvoiceUnit", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// This deletes an invoice unit with the provided invoice unit ARN.
    ///
    /// Parameters:
    ///   - invoiceUnitArn:  The ARN to identify an invoice unit. This information can't be modified or deleted.
    ///   - logger: Logger use during operation
    @inlinable
    public func deleteInvoiceUnit(
        invoiceUnitArn: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> DeleteInvoiceUnitResponse {
        let input = DeleteInvoiceUnitRequest(
            invoiceUnitArn: invoiceUnitArn
        )
        return try await self.deleteInvoiceUnit(input, logger: logger)
    }

    /// This retrieves the invoice unit definition.
    @Sendable
    @inlinable
    public func getInvoiceUnit(_ input: GetInvoiceUnitRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> GetInvoiceUnitResponse {
        try await self.client.execute(
            operation: "GetInvoiceUnit", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// This retrieves the invoice unit definition.
    ///
    /// Parameters:
    ///   - asOf:  The state of an invoice unit at a specified time. You can see legacy invoice units that are currently deleted if the AsOf time is set to before it was deleted. If an AsOf is not provided, the default value is the current time.
    ///   - invoiceUnitArn:  The ARN to identify an invoice unit. This information can't be modified or deleted.
    ///   - logger: Logger use during operation
    @inlinable
    public func getInvoiceUnit(
        asOf: Date? = nil,
        invoiceUnitArn: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> GetInvoiceUnitResponse {
        let input = GetInvoiceUnitRequest(
            asOf: asOf, 
            invoiceUnitArn: invoiceUnitArn
        )
        return try await self.getInvoiceUnit(input, logger: logger)
    }

    /// Retrieves your invoice details programmatically, without line item details.
    @Sendable
    @inlinable
    public func listInvoiceSummaries(_ input: ListInvoiceSummariesRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListInvoiceSummariesResponse {
        try await self.client.execute(
            operation: "ListInvoiceSummaries", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Retrieves your invoice details programmatically, without line item details.
    ///
    /// Parameters:
    ///   - filter: Filters you can use to customize your invoice summary.
    ///   - maxResults: The maximum number of invoice summaries a paginated response can contain.
    ///   - nextToken: The token to retrieve the next set of results. Amazon Web Services provides the token when the response from a previous call has more results than the maximum page size.
    ///   - selector: The option to retrieve details for a specific invoice by providing its unique ID. Alternatively, access information for all invoices linked to the account by providing an account ID.
    ///   - logger: Logger use during operation
    @inlinable
    public func listInvoiceSummaries(
        filter: InvoiceSummariesFilter? = nil,
        maxResults: Int? = nil,
        nextToken: String? = nil,
        selector: InvoiceSummariesSelector,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListInvoiceSummariesResponse {
        let input = ListInvoiceSummariesRequest(
            filter: filter, 
            maxResults: maxResults, 
            nextToken: nextToken, 
            selector: selector
        )
        return try await self.listInvoiceSummaries(input, logger: logger)
    }

    /// This fetches a list of all invoice unit definitions for a given account, as of the provided AsOf date.
    @Sendable
    @inlinable
    public func listInvoiceUnits(_ input: ListInvoiceUnitsRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListInvoiceUnitsResponse {
        try await self.client.execute(
            operation: "ListInvoiceUnits", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// This fetches a list of all invoice unit definitions for a given account, as of the provided AsOf date.
    ///
    /// Parameters:
    ///   - asOf:  The state of an invoice unit at a specified time. You can see legacy invoice units that are currently deleted if the AsOf time is set to before it was deleted. If an AsOf is not provided, the default value is the current time.
    ///   - filters:  An optional input to the list API. If multiple filters are specified, the returned list will be a configuration that match all of the provided filters. Supported filter types are InvoiceReceivers, Names, and Accounts.
    ///   - maxResults: The maximum number of invoice units that can be returned.
    ///   - nextToken: The next token used to indicate where the returned list should start from.
    ///   - logger: Logger use during operation
    @inlinable
    public func listInvoiceUnits(
        asOf: Date? = nil,
        filters: Filters? = nil,
        maxResults: Int? = nil,
        nextToken: String? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListInvoiceUnitsResponse {
        let input = ListInvoiceUnitsRequest(
            asOf: asOf, 
            filters: filters, 
            maxResults: maxResults, 
            nextToken: nextToken
        )
        return try await self.listInvoiceUnits(input, logger: logger)
    }

    /// Lists the tags for a resource.
    @Sendable
    @inlinable
    public func listTagsForResource(_ input: ListTagsForResourceRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListTagsForResourceResponse {
        try await self.client.execute(
            operation: "ListTagsForResource", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Lists the tags for a resource.
    ///
    /// Parameters:
    ///   - resourceArn: The Amazon Resource Name (ARN) of tags to list.
    ///   - logger: Logger use during operation
    @inlinable
    public func listTagsForResource(
        resourceArn: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListTagsForResourceResponse {
        let input = ListTagsForResourceRequest(
            resourceArn: resourceArn
        )
        return try await self.listTagsForResource(input, logger: logger)
    }

    /// Adds a tag to a resource.
    @Sendable
    @inlinable
    public func tagResource(_ input: TagResourceRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> TagResourceResponse {
        try await self.client.execute(
            operation: "TagResource", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Adds a tag to a resource.
    ///
    /// Parameters:
    ///   - resourceArn: The Amazon Resource Name (ARN) of the tags.
    ///   - resourceTags:  Adds a tag to a resource.
    ///   - logger: Logger use during operation
    @inlinable
    public func tagResource(
        resourceArn: String,
        resourceTags: [ResourceTag],
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> TagResourceResponse {
        let input = TagResourceRequest(
            resourceArn: resourceArn, 
            resourceTags: resourceTags
        )
        return try await self.tagResource(input, logger: logger)
    }

    ///  Removes a tag from a resource.
    @Sendable
    @inlinable
    public func untagResource(_ input: UntagResourceRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> UntagResourceResponse {
        try await self.client.execute(
            operation: "UntagResource", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    ///  Removes a tag from a resource.
    ///
    /// Parameters:
    ///   - resourceArn:  The Amazon Resource Name (ARN) to untag.
    ///   - resourceTagKeys:  Keys for the tags to be removed.
    ///   - logger: Logger use during operation
    @inlinable
    public func untagResource(
        resourceArn: String,
        resourceTagKeys: [String],
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> UntagResourceResponse {
        let input = UntagResourceRequest(
            resourceArn: resourceArn, 
            resourceTagKeys: resourceTagKeys
        )
        return try await self.untagResource(input, logger: logger)
    }

    /// You can update the invoice unit configuration at any time, and Amazon Web Services will use the latest configuration at the end of the month.
    @Sendable
    @inlinable
    public func updateInvoiceUnit(_ input: UpdateInvoiceUnitRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> UpdateInvoiceUnitResponse {
        try await self.client.execute(
            operation: "UpdateInvoiceUnit", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// You can update the invoice unit configuration at any time, and Amazon Web Services will use the latest configuration at the end of the month.
    ///
    /// Parameters:
    ///   - description: The assigned description for an invoice unit. This information can't be modified or deleted.
    ///   - invoiceUnitArn: The ARN to identify an invoice unit. This information can't be modified or deleted.
    ///   - rule: The InvoiceUnitRule object used to update invoice units.
    ///   - taxInheritanceDisabled: Whether the invoice unit based tax inheritance is/ should be enabled or disabled.
    ///   - logger: Logger use during operation
    @inlinable
    public func updateInvoiceUnit(
        description: String? = nil,
        invoiceUnitArn: String,
        rule: InvoiceUnitRule? = nil,
        taxInheritanceDisabled: Bool? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> UpdateInvoiceUnitResponse {
        let input = UpdateInvoiceUnitRequest(
            description: description, 
            invoiceUnitArn: invoiceUnitArn, 
            rule: rule, 
            taxInheritanceDisabled: taxInheritanceDisabled
        )
        return try await self.updateInvoiceUnit(input, logger: logger)
    }
}

extension Invoicing {
    /// Initializer required by `AWSService.with(middlewares:timeout:byteBufferAllocator:options)`. You are not able to use this initializer directly as there are not public
    /// initializers for `AWSServiceConfig.Patch`. Please use `AWSService.with(middlewares:timeout:byteBufferAllocator:options)` instead.
    public init(from: Invoicing, patch: AWSServiceConfig.Patch) {
        self.client = from.client
        self.config = from.config.with(patch: patch)
    }
}

// MARK: Paginators

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension Invoicing {
    /// Return PaginatorSequence for operation ``listInvoiceSummaries(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func listInvoiceSummariesPaginator(
        _ input: ListInvoiceSummariesRequest,
        logger: Logger = AWSClient.loggingDisabled
    ) -> AWSClient.PaginatorSequence<ListInvoiceSummariesRequest, ListInvoiceSummariesResponse> {
        return .init(
            input: input,
            command: self.listInvoiceSummaries,
            inputKey: \ListInvoiceSummariesRequest.nextToken,
            outputKey: \ListInvoiceSummariesResponse.nextToken,
            logger: logger
        )
    }
    /// Return PaginatorSequence for operation ``listInvoiceSummaries(_:logger:)``.
    ///
    /// - Parameters:
    ///   - filter: Filters you can use to customize your invoice summary.
    ///   - maxResults: The maximum number of invoice summaries a paginated response can contain.
    ///   - selector: The option to retrieve details for a specific invoice by providing its unique ID. Alternatively, access information for all invoices linked to the account by providing an account ID.
    ///   - logger: Logger used for logging
    @inlinable
    public func listInvoiceSummariesPaginator(
        filter: InvoiceSummariesFilter? = nil,
        maxResults: Int? = nil,
        selector: InvoiceSummariesSelector,
        logger: Logger = AWSClient.loggingDisabled        
    ) -> AWSClient.PaginatorSequence<ListInvoiceSummariesRequest, ListInvoiceSummariesResponse> {
        let input = ListInvoiceSummariesRequest(
            filter: filter, 
            maxResults: maxResults, 
            selector: selector
        )
        return self.listInvoiceSummariesPaginator(input, logger: logger)
    }

    /// Return PaginatorSequence for operation ``listInvoiceUnits(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func listInvoiceUnitsPaginator(
        _ input: ListInvoiceUnitsRequest,
        logger: Logger = AWSClient.loggingDisabled
    ) -> AWSClient.PaginatorSequence<ListInvoiceUnitsRequest, ListInvoiceUnitsResponse> {
        return .init(
            input: input,
            command: self.listInvoiceUnits,
            inputKey: \ListInvoiceUnitsRequest.nextToken,
            outputKey: \ListInvoiceUnitsResponse.nextToken,
            logger: logger
        )
    }
    /// Return PaginatorSequence for operation ``listInvoiceUnits(_:logger:)``.
    ///
    /// - Parameters:
    ///   - asOf:  The state of an invoice unit at a specified time. You can see legacy invoice units that are currently deleted if the AsOf time is set to before it was deleted. If an AsOf is not provided, the default value is the current time.
    ///   - filters:  An optional input to the list API. If multiple filters are specified, the returned list will be a configuration that match all of the provided filters. Supported filter types are InvoiceReceivers, Names, and Accounts.
    ///   - maxResults: The maximum number of invoice units that can be returned.
    ///   - logger: Logger used for logging
    @inlinable
    public func listInvoiceUnitsPaginator(
        asOf: Date? = nil,
        filters: Filters? = nil,
        maxResults: Int? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) -> AWSClient.PaginatorSequence<ListInvoiceUnitsRequest, ListInvoiceUnitsResponse> {
        let input = ListInvoiceUnitsRequest(
            asOf: asOf, 
            filters: filters, 
            maxResults: maxResults
        )
        return self.listInvoiceUnitsPaginator(input, logger: logger)
    }
}

extension Invoicing.ListInvoiceSummariesRequest: AWSPaginateToken {
    @inlinable
    public func usingPaginationToken(_ token: String) -> Invoicing.ListInvoiceSummariesRequest {
        return .init(
            filter: self.filter,
            maxResults: self.maxResults,
            nextToken: token,
            selector: self.selector
        )
    }
}

extension Invoicing.ListInvoiceUnitsRequest: AWSPaginateToken {
    @inlinable
    public func usingPaginationToken(_ token: String) -> Invoicing.ListInvoiceUnitsRequest {
        return .init(
            asOf: self.asOf,
            filters: self.filters,
            maxResults: self.maxResults,
            nextToken: token
        )
    }
}
